<script lang="ts" setup>
import * as productApi from "@/api/train/product";
import * as orderApi from "@/api/train/order";
import * as payUtils from "@/utils/pay";
import * as payApi from "@/api/pay";
import Sku from "@/components/sku.vue";
import Notice from "./components/notice.vue";
import Collect from "./components/collect.vue";
import BottomBar from "./components/bottom-bar.vue";
import OrderInfo from "./components/order-info.vue";
import Countdown from "./components/countdown.vue";
import { useRouter } from "vue-router";
import { showToast } from "@nutui/nutui";
import { isMiniProgram } from "@/utils/mini-program";
import wx from "weixin-js-sdk";
import { buildParams, sleep } from "@/utils/utils";
import { useUserStore } from "@/store/modules/user";

const props = defineProps({
  skuId: {
    type: String,
    required: true,
  },
});

const router = useRouter();
const userStore = useUserStore();

/** 订单信息 */
const order = ref<OrderInfoResp | null>(null);

/** 用户信息收集组件 */
const collectRef = ref<InstanceType<typeof Collect> | null>(null);

// 判断是否是成功驾校
const isAppointUser = ref<boolean>(userStore.tenantInfo?.id === "1699754050142015488");
// 是否确认协议
const isAgreement = ref(false);
const isShowPopup = ref<boolean>(false);

/** sku信息 */
const sku = ref<ProductSku | null>(null);
productApi.getSkuById(props.skuId).then((res) => {
  sku.value = res.data;
  console.log(sku.value);
});

// 是否包含班型产品
const hasBindClass = computed(
  () =>
    // bindType=3 的为班型产品
    sku.value?.skuBindList?.some((item) => item.bindType === 3)
);

/** 数量和总价 */
const amount = ref(1);
const total = computed(() => {
  return amount.value * (sku.value?.price || 0);
});

/** 创建订单 */
async function createOrder() {
  // 判断是否是成功驾校
  if (isAppointUser.value && hasBindClass.value) {
    // 展开弹窗
    if (!isAgreement.value) {
      isShowPopup.value = true;
      return;
    }
  }
  const res = await orderApi.createOrder({
    skuId: props.skuId,
    amount: amount.value,
    orderPrice: total.value,
    remark: collectRef.value?.getUserRemark() || "",
    signUpInfo: hasBindClass.value ? JSON.stringify(collectRef.value?.getContactInfo()) : undefined,
    signMemberId: userStore.shareInfo.userId || undefined,
  });

  const orderId = res.data;
  const orderRes = await orderApi.getOrderById(orderId);
  order.value = orderRes.data;
  scrollTo({
    top: 0,
    behavior: "smooth",
  });
}

/** 调起支付 */
async function payOrder(order: OrderInfoResp) {
  if (order.orderPrice === 0) {
    // TODO: 新建一个接口：调用该订单的支付成功的回调（更新状态等）
  }

  // 小程序支付
  if (isMiniProgram()) {
    showToast.text("正在发起小程序支付...");

    const paramsStr = buildParams({
      orderId: order.id,
      accessToken: userStore.auth.accessToken,
    });

    wx.miniProgram.navigateTo({ url: `/pages/pay/pay?${paramsStr}` });
    router.back();
    return;
  }

  // 创建支付订单
  showToast.loading("正在发起支付...", {
    duration: 0,
    cover: true,
  });
  const res = await payApi.unifiedOrder(order.id);
  showToast.hide();

  // 解析支付数据
  const {
    data: {
      data: { payData: payDataOrigin },
    },
  } = res;
  const payData: PayData = JSON.parse(payDataOrigin);
  const prepayId = payData.package.match(/prepay_id=(.+)/)?.[1];
  if (!prepayId) return showToast.fail("支付数据解析失败");

  // 发起微信支付
  try {
    showToast.loading("支付中...", {
      duration: 0,
      cover: true,
    });
    const res = await payUtils.requestH5Payment(payData);
    console.log("支付成功：", res);
    showToast.hide();
    // showToast.success("支付成功");
    showToast.loading("正在等待支付结果...");
    await sleep(2000);
    showToast.hide();
    router.replace(`/order/${order.orderNo}`);
  } catch (e) {
    console.log("支付失败：", e);
    showToast.hide();
    showToast.fail("支付失败");
    expired.value = true;
  }
}

/** 取消订单 */
async function cancelOrder(order: OrderInfoResp) {
  const res = await orderApi.cancelOrder(order.id);
  if (res) {
    // 取消成功
    router.replace(`/order/${order.orderNo}`);
  }
}

/** 订单过期事件 */
const expired = ref(false);

// 获取金额上的各位数
const getDigit = (digit: number) => {
  let num = Math.trunc(total.value / digit).toString();
  return num.charAt(num.length - 1);
};

// 成功确认合同后直接跳转
const handleAgreement = () => {
  isAgreement.value = true;
  isShowPopup.value = false;
  createOrder();
};
</script>

<template>
  <div class="min-h-screen py-3 bg-gray-1">
    <!-- 订单支付倒计时 -->
    <countdown v-if="order" :pay-price="order.orderPrice" :timeout="10 * 60" v-model:expired="expired" />

    <!-- 商品卡片 -->
    <div class="m-3 mt-0 p-3 rd-lg bg-white">
      <!-- sku信息 -->
      <sku v-if="sku" :sku="sku" />

      <!-- 包含服务 -->
      <div v-if="sku?.skuBindList" class="mt-5">
        <span>包含服务: </span>
        <div v-for="item in sku.skuBindList" :key="item.bindId">
          <span class="c-gray-4">{{ item.bindTitle }}</span>
        </div>
      </div>

      <!-- 购买数量 -->
      <div class="mt-5 flex justify-between">
        <span>购买份数</span>
        <span class="c-gray-4">{{ amount }}份</span>
      </div>

      <!-- 小计 -->
      <div class="mt-5 text-right">
        小计 <span class="text-xs">￥</span><span class="text-lg">{{ total / 100 }}</span>
      </div>
    </div>

    <!-- 联系方式 -->
    <div class="mx-3 mt-5 rd-lg">
      <collect ref="collectRef" enable-user-remark :enable-contact-info="hasBindClass" :disabled="!!order" />
    </div>

    <!-- 购买须知 -->
    <notice v-if="!order && sku?.payNote" :payNote="sku?.payNote" />
    <!-- 订单信息 -->
    <order-info v-if="order" :order-info="order" :expired="expired" />

    <!-- 底部栏 -->
    <bottom-bar :total="total" :order="order" :expired="expired" @create-order="createOrder" @pay-order="payOrder" @cancel-order="cancelOrder" />

    <!-- 成功用户协议 -->
    <nut-popup position="bottom" :close-on-click-overlay="false" closeable :style="{ height: '85%' }" v-model:visible="isShowPopup">
      <div class="p-3">
        <p class="mb-2 text-xl text-center font-bold">成功驾校培训合同</p>
        <p>
          <span>甲方：乐平市成功驾驶员培训有限公司</span>
        </p>
        <p>
          <span>乙方：{{ collectRef?.getContactInfo().name }}（学员姓名）</span>
        </p>
        <p>
          <span> &nbsp; &nbsp; 身份证号码：</span>
        </p>
        <p>
          <span> &nbsp; &nbsp; 联系电话：{{ collectRef?.getContactInfo().phone }}</span>
        </p>
        <p style="text-indent: 21pt">
          <span>甲乙双方根据</span
          ><span class="font-bold" style="font-family: 微软雅黑"
            >《中国人民共和国合同法》等有关法律、法规规定，本着平等、自愿、有偿、诚实守信的原则，经甲乙双方签字确认，签订本合同，并具有法律效力。</span
          >
        </p>
        <p><span class="font-bold" style="font-family: 微软雅黑">一、收费情况</span></p>
        <p>
          <span class="font-bold" style="font-family: 微软雅黑">1、乙方向甲方缴学费</span
          ><span
            >￥ {{ getDigit(100) }} 元（人民币大写： {{ getDigit(1000000) }}万 {{ getDigit(100000) }} 千 {{ getDigit(10000) }} 佰
            {{ getDigit(1000) }} 拾 {{ getDigit(100) }}元整）</span
          >
        </p>
        <p style="text-indent: 10.5pt">
          <span
            >2、乙方向甲方预缴学费￥__ 元（人民币大写：__万 __ 千 __ 佰 __ 拾__元整），尾款￥__ 元（人民币大写：__万__ 千__ 佰__
            拾___元整）须在预约科目二考试前交清。</span
          >
        </p>
        <p><span> </span></p>
        <p><span>二、服务内容</span></p>
        <p>
          <span>
            乙方申报学籍准驾车型代码为：___，乙方完成报名手续并缴清有关费用费用后，乙方委托甲方代为办理机动车驾驶证申领的相关手续，甲方为乙方提供培训相关服务事宜。</span
          >
        </p>
        <p><span> </span></p>
        <p><span>三、主要责任和义务</span></p>
        <p>
          <span>
            1、
            &nbsp;乙方须保证提供的证件及相关信息的真实。因提交的证件虚假或提供的信息错误而造成资料未能在交警部门受理，产生的相关费用由乙方承担。甲方有权扣除相关服务费用。</span
          >
        </p>
        <p><span> </span></p>
        <p>
          <span>2、因乙方自身原因需要转移档案，乙方单方终止对乙方的培训服务，则视为乙方违约，乙方无权要求甲方退款。</span>
        </p>
        <p><span>3、因乙方原因造成机动车驾驶技能证明三年过期失效，则所交费用均不予退还。</span></p>
        <p>
          <span
            >4、依照有关规定，在乙方驾驶技能证明有效期三年内，科目二和科目三道理驾驶技能考试预约次数不得超过五次，若第五次预约考试仍不合格的，所有科目的成绩将作废，如乙方因此放弃继续培训，所交费用不予退还；若乙方仍需要参加培训考试的，应当重新签订培训合同商定应缴纳费用。</span
          >
        </p>
        <p><span>四、退学退费</span></p>
        <p><span> &nbsp;乙方中途要求退学，甲乙双方可协调一致后办理退费事宜：</span></p>
        <p>
          <span
            >1、乙方要求中途退学时，且乙方资料档案因乙方自身原因未在车管所建档受理的，C照类、摩托车类、资格证类扣除200元的资料费及业务服务费，AB照类扣除500元的资料费及业务服务费；已由甲方对乙方资料档案在车管所建档受理成功的，C照类扣除建档费900元，大车A、B照扣除1200元建档费；已产生科目二、科目三学时的，也需另扣除产生的相关学时培训费用。大车学时按照150元/学时（1学时=45分钟），小车学时按照120元/学时（1学时=45分钟）计算，已预约或已参加科目一考试的，C照类扣除1200元，AB照扣除1600元的费用，若产生学时则另外扣除产生学时的费用;如通过线上平台报名的，乙方在建档受理前要求退费的需扣除百分之六的平台服务费，已建档受理、预约考试、产生实操学时的，还需扣除相应的建档费、预约考试费、学时费用等。</span
          >
        </p>
        <p><span>2、乙方已进入科目三计时培训的不予退费。</span></p>
        <p><span>五、违约责任</span></p>
        <p>
          <span>1、如甲方在未遇不可抗力的因素且乙方未违约的情况下，甲方终止对乙方的培训服务，则视为甲方违约，甲方须无条件全额退款给乙方。</span>
        </p>
        <p>
          <span>2、如乙方在培训期间未向甲方缴纳本合同规定的相关费用，甲方有权暂时终止安排对乙方相应阶段的培训及考试，由此造成后果由乙方承担。</span>
        </p>
        <p><span> </span></p>
        <p><span>六、争议的解决</span></p>
        <p><span>1、合同履行过程中发生争议时，甲乙双方可协商解决，协商不成时，可向驾校所在地人民法院提出诉讼。</span></p>
        <p><span>2、本合同一式两份，甲乙双方各执一份，自双方签订并付款之日起生效。</span></p>
        <p><span>3、本合同有未尽事宜的，按国家有关法律、法规办理。</span></p>
        <p><span> </span></p>
        <p><span> </span></p>
        <p><span> </span></p>
        <p>
          <span>甲方盖章： &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 乙方（代表人）：{{ collectRef?.getContactInfo().name }}</span>
        </p>
        <p>
          <span>
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 签订时间：
            {{ new Date().getFullYear() }} 年 {{ new Date().getMonth() + 1 }}月 {{ new Date().getDate() }}日</span
          >
        </p>
        <p><br /></p>

        <!-- 确定 -->
        <div class="flex justify-around">
          <nut-button class="w-30!" type="default" @click="isShowPopup = false">取消</nut-button>
          <nut-button class="w-30!" type="info" @click="handleAgreement">确定</nut-button>
        </div>
      </div>
    </nut-popup>
  </div>
</template>

<style scoped>
p {
  padding: 4px;
}
</style>
